package com.tundriki.pref;

import javax.microedition.khronos.opengles.GL10;

import android.util.FloatMath;

import java.nio.FloatBuffer;


public class Card {
	
	private float x = 0f, y = 0f, z=0f,
			angle = 0;
	private float norm[] = {0,0,1f,0};
	public final String name;
	public final String suit;
	public final TextureBundle tex;
	public final int faceTex, backTex;
	private final double aMult = (Math.PI / 180);
	private final int vertCount;
	private FloatBuffer cVx; // card face vertices.
	
	private float[] dbgPoint = null;
	private boolean dbgDraw = false;
	
	public Card(TextureBundle tex, String name) {
		super();
		int i = name.indexOf(" of ");
		
		this.name = name;
		this.tex = tex;
		suit = i>=0?this.name.substring(i+4):"";
		faceTex = this.tex.texByName(this.name);
		backTex = this.tex.texByName("shirt");
		cVx = TextureBundle.createBuffer(tex.cardShape);
		this.vertCount = tex.cardShape.length/3;
		
		genCoordArrays();
	}
	
	public boolean higherThan(Card c) {
		if (c!=null)
			return z>c.z;
		return false;
	}
	
	private void genCoordArrays() {
		float cos, sin, x, y, z/*, r*/;
		
		cVx.position(0);
		cos = FloatMath.cos((float)(angle * aMult));
		sin = FloatMath.sin((float)(angle * aMult));
		
		for (int i=0;i<tex.cardShape.length;i+=3) {
			y = this.y + tex.cardShape[i+1];
			// mathematically right
			/* r = (float)Math.sqrt((double)vx[i]*vx[i]+vx[i+1]*vx[i+2]);
			x = this.x + r*cos;
			z = this.z + r*sin;*/
			//suggest that model has z=0 in all vertices
			x = this.x + tex.cardShape[i]*cos;
			z = this.z + tex.cardShape[i]*sin;
			
			cVx.put(x);	cVx.put(y);	cVx.put(z);
		}
		// Calculate normal vector
		norm = GeomSolver.normal(cVx);
	}

	
	public float getAngle() {
		return angle;
	}
	
	public float getX() {
		return x;
	}
	public float getY() {
		return y;
	}
	public float getZ() {
		return z;
	}
	
	public void moveTo(float nX, float nY, float nZ) {
		x = nX;
		y = nY;
		z = nZ;
		genCoordArrays();
	}
	
	public void moveBy(float dX, float dY, float dZ) {
		x += dX;
		y += dY;
		z += dZ;
		genCoordArrays();
	}
	
	private void normAngle() {
		angle -= 360f * android.util.FloatMath.floor(angle/360f);
		if (angle>180f)
			angle -= 360f;
		else if (angle<-180)
			angle += 360f;
	}
	
	public void rotateTo(float nAngle) {
		angle = nAngle;
		normAngle();
		genCoordArrays();
	}
	
	public void rotateBy(float dAngle) {
		angle += dAngle;
		normAngle();
		genCoordArrays();
	}
	
	public void hideFace() {
		rotateTo(180);
	}
	
	public void showFace() {
		rotateTo(0);
	}
	
	public void reinit() {
		moveTo(0,0,0);
		rotateTo(0);
	}
	
	public void draw(GL10 gl) {
		gl.glColor4f(1f, 1f, 1f, 0f);
	    
		cVx.position(0);
		tex.stdTexMap.position(0);

		//Select texture face or back
		if (angle<90 && angle>-90)
			gl.glBindTexture(GL10.GL_TEXTURE_2D, faceTex);
		else
			gl.glBindTexture(GL10.GL_TEXTURE_2D, backTex);

	    gl.glFrontFace(GL10.GL_CW);
	    
	    /* draw card */
	    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cVx);
	    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tex.stdTexMap);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertCount);
	    if (dbgDraw) {
	    	dbgDrawPoint(gl);
	    }
	}
	
	private void dbgDrawPoint(GL10 gl) {
		FloatBuffer b = TextureBundle.createBuffer(9);
		
//	    gl.glFrontFace(GL10.GL_CCW);
//	    gl.glEnable(GL10.GL_CULL_FACE);
//	    gl.glCullFace(GL10.GL_BACK);
	    
	    b.put(dbgPoint[0]);
	    b.put(dbgPoint[1]-0.05f);
	    b.put(dbgPoint[2]+0.01f);
	    b.put(dbgPoint[0]+0.06f);
	    b.put(dbgPoint[1]+0.05f);
	    b.put(dbgPoint[2]+0.01f);
	    b.put(dbgPoint[0]-0.06f);
	    b.put(dbgPoint[1]+0.05f);
	    b.put(dbgPoint[2]+0.01f);
	    b.position(0);
	    

	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		
		//gl.glDepthMask(false);
		gl.glColor4f(1f, 0.8f, 0.1f, 1f);
		gl.glLineWidth(5f);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, b);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
		
		
//        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//        gl.glDisable(GL10.GL_CULL_FACE);

		
		//gl.glDepthMask(true);
	}
	
	public boolean sameSuit(Card card) {
		return card.suit.equals(this.suit);
	}

	public boolean winOver(Card card, String trump) {
		if (this.sameSuit(card))
			return CardComparator._compare(this,card) > 0;
		else if(this.suit.equals(trump))
			return true;
		return false;
	}
	
	public boolean samePosition(float X, float Y, float Z) {
		return Math.abs(x-X)<0.0001 && Math.abs(y-Y)<0.0001 && Math.abs(y-Y)<0.0001;
	}
	
	
	public boolean intersection(float[][] coord) {
		int[] vertOrder = {0,1,3,2};
		dbgPoint = GeomSolver.planeIntersection(norm, coord);
		if (!(dbgDraw = !(dbgPoint==null))) 
			return false;
		return GeomSolver.pointInsidePolygon(cVx, vertOrder, dbgPoint);
	}
	
	
}
